package com.huluobo.lib_base.mvvm

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.huluobo.lib_base.net.Res
import kotlinx.coroutines.launch
import java.lang.RuntimeException
import kotlin.Exception

/**
 *  Created by LC on 2025/9/13.
 */
open class BaseViewModel : ViewModel() {

    //声明所有网络请求的错误  Throwable代表错误类型,类似于异常
    val onFailed by lazy { MutableLiveData<Throwable>() }

    //执行网络请求的方法,T代表返回类型,比如请求Login的时候,返回值就是一个UserBean
    //请求Video列表的时候,返回值就是一个VideoList
    fun <T> executeNetwork(
        //请求方法,比如login,这里就传入ApiService中的login方法
        s: suspend () -> Res<T>,
        //成功的回调,需要传入一个方法
        success: (T) -> Unit,
        // (Throwable) -> Unit 这是一个方法,参数类型是Throwable
        //= 代表参数的默认值,
        failed: (Throwable) -> Unit = onFailed::postValue,
        //状态码
        okCode: Int = 200
    ) {
        //开启ViewModel作用域的协程,这个协程跟随ViewModel的生命周期
        viewModelScope.launch {
            try {
                //调用一次s的方法,产生返回值
                val res = s.invoke()
                if (res.code == okCode) {
                    success(res.data)
                } else {
                    failed(RuntimeException(res.message))
                }
            } catch (e: Exception) {
                //请求如果产生错误,调用failed方法,把异常传递给onFailed的postValue
                failed(e)
            }
        }
    }

    //执行数据库请求的方法
    fun <T> executeDb(
        //Dao中的增删改查方法
        s: suspend () -> T,
        //成功的LiveData
        success: (T) -> Unit,
        //失败的LiveData,有默认值,可以直接在onFailed中添加值
        failed: (Throwable) -> Unit = onFailed::postValue
    ) {
        //开启ViewModel的协程作用域
        viewModelScope.launch {
            try {
                //如果不产生异常,直接将s方法的调用结果(返回值)添加到成功中
                success(s.invoke())
            } catch (e: Exception) {
                //如果产生异常,将异常添加到失败的LiveData中
                failed(e)
            }
        }
    }
}